#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
主题: 字符串令牌解析
问题: 你有一个字符串，想从左至右将其解析为一个令牌流。
提示:
    1. 确认你使用正则表达式指定了所有输入中可能出现的文本序列。 如果有任何不可匹配的文本出现了，扫描就会直接停止
"""

from collections import namedtuple
import re

text = 'foo = 42'
print(f"{text = }")

def recipe1():
    import re
    NAME = r'(?P<NAME>[a-zA-Z_][a-zA-Z_0-9]*)'
    NUM = r'(?P<NUM>\d+)'
    PLUS = r'(?P<PLUS>\+)'
    TIMES = r'(?P<TIMES>\*)'
    EQ = r'(?P<EQ>=)'
    WS = r'(?P<WS>\s+)'

    master_pat = re.compile('|'.join([NAME, NUM, PLUS, TIMES, EQ, WS]))
    scanner = master_pat.scanner(text)

    m = scanner.match()
    print(f"{(m.lastgroup, m.group()) = }")

    m = scanner.match()
    print(f"{(m.lastgroup, m.group()) = }")

    m = scanner.match()
    print(f"{(m.lastgroup, m.group()) = }")

    m = scanner.match()
    print(f"{(m.lastgroup, m.group()) = }")

    m = scanner.match()
    print(f"{(m.lastgroup, m.group()) = }")

    for tok in generate_token(master_pat, text):
        print(f"{tok = }")

    # 过滤令牌流
    tokens = (tok for tok in generate_token(master_pat, text) if tok.type != 'WS') # 生成器表达式
    for tok in tokens:
        print(f"{tok = }")

def recipe2():
    PRINT = r'(?P<PRINT>print)'
    NAME = r'(?P<NAME>[a-zA-Z_][a-zA-Z_0-9]*)'

    master_pat = re.compile('|'.join([PRINT, NAME]))
    for tok in generate_token(master_pat, 'printer'):
        print(f"{tok = }")

Token = namedtuple('Token', ['type', 'value'])                  
def generate_token(pat, text):
    """生成器"""
    scanner = pat.scanner(text)
    for m in iter(scanner.match, None):
        yield Token(m.lastgroup, m.group())

def main():
    print('recipe1'.center(20, '*'))
    recipe1()
    print('recipe2'.center(20, '*'))
    recipe2()

if __name__ == '__main__':
    main()          